package fons.model.ontology.language;

import java.lang.reflect.Constructor;
import java.util.Map;

import com.google.common.collect.Maps;

public class SentenceElementMixinFactory {
	private Map<Class<?>, Class<? extends SentenceElementMixin>> classes = Maps.newHashMap();

	public SentenceElement decorate(SentenceElement sentenceElement) {
		Class<?> referenceClass = sentenceElement.getReferenceClass();
		Class<? extends SentenceElement> sentenceElementClass = null;

		if (classes.containsKey(referenceClass)) {
			sentenceElementClass = classes.get(referenceClass);

		} else {
			Class<?> testClass = referenceClass;
			while (sentenceElementClass == null) {
				if (testClass.getCanonicalName() != null) { 
					try {
						sentenceElementClass = Class.forName(this.getClass().getPackage().getName() 
								+ '.' + testClass.getSimpleName()
								+ "SentenceElement").asSubclass(SentenceElement.class);
					} catch (Exception e) {
						System.out.println("No constructor for " + testClass.getSimpleName() + " found!");
					}
				}
				testClass = testClass.getSuperclass();
				if (testClass == null) break;
			}
		}

		try {
			Constructor<? extends SentenceElement> constructor 
			= sentenceElementClass.getConstructor(SentenceElement.class);
			return constructor.newInstance(sentenceElement);

		} catch (Exception e) {
			e.printStackTrace();
			return new UnknownSentenceElement(sentenceElement);
		}
	}

	public void addSentenceElementMixin(Class<?> reference,
			Class<? extends SentenceElementMixin> sentenceElement) {
		classes.put(reference, sentenceElement);
	}

}
